package com.example.springboot.util;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.BytesRef;

import java.io.File;
import java.io.IOException;

/**
 * Created by tangmayao on 2018/4/4.
 */
public class SearchUtil {

    private static SearchUtil searchUtil;
    private Directory directory;
    private IndexReader indexReader;
    private IndexSearcher indexSearcher;

    private SearchUtil() {
    }


    public static SearchUtil getInstance() {
        if (searchUtil == null) {

            return new SearchUtil();
        }
        return searchUtil;
    }


    public void initSearchUtil() {
        try {
            directory = FSDirectory.open(new File("E:\\java-source\\lucene\\lucene-index\\2"));
            indexReader = DirectoryReader.open(directory);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 实现近实时查询，不关闭reader，但是Index有变化时，重新获取reader
     **/
    private IndexSearcher getSearcher() {
        try {
            if (indexReader == null) {
                indexReader = DirectoryReader.open(directory);
            } else {
                DirectoryReader tr = DirectoryReader.openIfChanged((DirectoryReader) indexReader);
                if (tr != null) {
                    indexReader.close();
                    indexReader = tr;
                }
            }
            return new IndexSearcher(indexReader);
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;

    }

    /**
     * termquery
     */

    public void searchByTerm(String field, String name, int num) {
        indexSearcher = this.getSearcher();
        Query query = new TermQuery(new Term(field, name));

        try {
            TopDocs topDocs = indexSearcher.search(query, num);
            ScoreDoc[] scoreDocs = topDocs.scoreDocs;
            for (ScoreDoc scoreDoc : scoreDocs) {

                Document document = indexSearcher.doc(scoreDoc.doc);
                System.out.println("查到了:" + document.get("name") + ",," + document.get("email") + ",,,," + document.get("content"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    public void searchByTermRange(String field, String begin, String end, int num) {
        indexSearcher = this.getSearcher();
        Query query = new TermRangeQuery(field, new BytesRef(begin.getBytes()), new BytesRef(end.getBytes()), true, true);
        try {
            TopDocs topDocs = indexSearcher.search(query, num);
            ScoreDoc[] scoreDocs = topDocs.scoreDocs;

            for (ScoreDoc scoreDoc : scoreDocs) {
                Document document = indexSearcher.doc(scoreDoc.doc);
                System.out.println("查到了:" + document.get("name") + ",," + document.get("email") + ",,,," + document.get("content"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void searchByQueryParser(Query query, int num) {
        indexSearcher = this.getSearcher();
        try {
            TopDocs topDocs = indexSearcher.search(query, num);
            ScoreDoc[] scoreDocs = topDocs.scoreDocs;

            for (ScoreDoc scoreDoc : scoreDocs) {
                Document document = indexSearcher.doc(scoreDoc.doc);
                System.out.println("查到了:" +document.get("id")+",,"+ document.get("name") + ",," + document.get("email") + ",,,," + document.get("content"));
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public  ScoreDoc  getLastScoreDoc(int pageIndex,int pageSize,Query query,IndexSearcher indexSearcher){

        if(pageIndex==1) {return null;}else {


           int lastPageNum=pageSize*(pageIndex-1);
            try {
                TopDocs topDocses= indexSearcher.search(query,lastPageNum);
                return topDocses.scoreDocs[lastPageNum-1];
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return  null;
    }


    public  void searchAfter(int pageIndex,int pageSize,Query query){
        indexSearcher=this.getSearcher();
        ScoreDoc lastScoreDoc=getLastScoreDoc(pageIndex,pageSize,query,indexSearcher);

        try {
            TopDocs topDocs= indexSearcher.searchAfter(lastScoreDoc,query,pageSize);

            ScoreDoc[] scoreDocs = topDocs.scoreDocs;

            for (ScoreDoc scoreDoc : scoreDocs) {
                Document document = indexSearcher.doc(scoreDoc.doc);
                System.out.println("查到了:" +document.get("id")+",,"+ document.get("name") + ",," + document.get("email") + ",,,," + document.get("content"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }


    }


}